package services

import (
	"GOPAAS/configs/config"
	"GOPAAS/internal/app/model"
	"GOPAAS/internal/utils"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/nfnt/resize"
	"github.com/pkg/errors"
	"image"
	"image/jpeg"
	"os"
	"path/filepath"
	"strings"
)

type AttachService struct {
	model.IrAttachment
}

func GetAttachService(aid int64) *AttachService {
	db = getDB()
	var attach model.IrAttachment
	if aid > 0 {
		db.First(&attach, aid)
	}
	return &AttachService{attach}
}

// DeleteAttach 删除应用附件
func (a *AttachService) DeleteAttach(res_id int64, res_model string, res_field string) (err error) {
	if a.ResModel != res_model || a.ResId != res_id || a.ResField.String != res_field {
		return errors.New("未找到该附件")
	}
	res := db.Delete(&a.IrAttachment)
	return res.Error
}

// DeleteAttaches 删除所有附件
func (a *AttachService) DeleteAttaches(res_id int64, res_model string, res_field string) (err error) {
	var attach model.IrAttachment
	db = getDB()
	res := db.Where("res_model=? and res_id=? and res_field=?", res_model, res_id, res_field).Delete(&attach)
	return res.Error
}

// AddRecord 插入附件数据
func (a *AttachService) AddRecord(user_id int64, file_name string, res_model string, res_field string, res_id int64, company_id int64, store_fname string, file_size int64, mine_type string) (attach model.IrAttachment, err error) {
	db = getDB()
	db.Where("res_model=? and res_id=? and res_field=?", res_model, res_id, res_field).First(&attach)
	var before_file string
	if attach.Id > 0 {
		db.Delete(&attach)
		before_file = config.Conf.DataDir + "/" + attach.StoreFname
	}
	attach = model.IrAttachment{
		Name:         file_name,
		ResModel:     res_model,
		ResField:     utils.NullStringValue(res_field),
		ResId:        res_id,
		CompanyId:    company_id,
		Type:         "binary",
		StoreFname:   store_fname,
		FileSize:     file_size,
		Checksum:     store_fname[3:],
		Mimetype:     mine_type,
		Active:       true,
		IndexContent: strings.Split(mine_type, "/")[0],
		ResCommon: model.ResCommon{
			CreateUid: user_id,
			WriteUid:  user_id,
		},
	}
	res := db.Select("Name", "ResModel", "ResField", "ResId", "CompanyId", "Type", "StoreFname", "FileSize", "Checksum", "Mimetype", "IndexContent", "CreateUid", "WriteUid", "active").Create(&attach)
	err = res.Error
	if err != nil && before_file != "" {
		//删除附件
		os.Remove(before_file)
	}
	return
}

// AppendRecord 插入附件数据(不删除)
func (a *AttachService) AppendRecord(user_id int64, file_name string, res_model string, res_field string, res_id int64, company_id int64, store_fname string, file_size int64, mine_type string) (attach model.IrAttachment, err error) {
	db = getDB()

	attach = model.IrAttachment{
		Name:         file_name,
		ResModel:     res_model,
		ResField:     utils.NullStringValue(res_field),
		ResId:        res_id,
		CompanyId:    company_id,
		Type:         "binary",
		StoreFname:   store_fname,
		FileSize:     file_size,
		Checksum:     store_fname[3:],
		Mimetype:     mine_type,
		Active:       true,
		IndexContent: strings.Split(mine_type, "/")[0],
		ResCommon: model.ResCommon{
			CreateUid: user_id,
			WriteUid:  user_id,
		},
	}
	res := db.Select("Name", "ResModel", "ResField", "ResId", "CompanyId", "Type", "StoreFname", "FileSize", "Checksum", "Mimetype", "IndexContent", "CreateUid", "WriteUid", "active").Create(&attach)
	err = res.Error
	return
}

// ResizeImgAndSave 缩放图片保存
func (a *AttachService) ResizeImgAndSave(img image.Image, dst string, size uint) (width int, height int, err error) {
	//缩放到1024比例保存
	img_1024 := resize.Resize(size, 0, img, resize.Lanczos3)

	imgfile, _ := os.Create(dst)
	err = jpeg.Encode(imgfile, img_1024, &jpeg.Options{100})
	if err != nil {
		imgfile.Close()
		return
	}
	imgfile.Close()
	new_img, _ := os.Open(dst)
	c, _, err := image.DecodeConfig(new_img)
	width = c.Width
	height = c.Height
	return
}

// GetAttach 获取附件
func (a *AttachService) GetAttach(res_model string, res_id int64, res_field string) (model.IrAttachment, error) {
	var attach model.IrAttachment
	db = getDB()
	q := db.Where("res_model=? and res_id=? and active=?", res_model, res_id, true)
	if res_field != "" {
		q.Where("res_field=?", res_field)
	} else {
		q.Where("res_field is null")
	}
	res := q.First(&attach)
	err := res.Error
	return attach, err
}

// GetAttachBySum 获取附件
func (a *AttachService) GetAttachBySum(check_sum string) (model.IrAttachment, error) {
	var attach model.IrAttachment
	db = getDB()
	res := db.Where("checksum=? and active=?", check_sum, true).First(&attach)
	err := res.Error
	return attach, err
}

// GetAttachBySumAndId 获取附件
func (a *AttachService) GetAttachBySumAndId(check_sum string, model_name string, res_id int64) (model.IrAttachment, error) {
	var attach model.IrAttachment
	db = getDB()
	res := db.Where("res_model=? and res_id=? and checksum=? and active=?", model_name, res_id, check_sum, true).First(&attach)
	err := res.Error
	return attach, err
}

type FileItem struct {
	Id         int64  `json:"id"`
	Url        string `json:"url"`
	PreviewUrl string `json:"preview_url"`
	Mimetype   string `json:"mimetype"`
	Name       string `json:"name"`
	Num        string `json:"num"`
	Unit       string `json:"unit"`
	Checksum   string `json:"checksum"`
	Icon       string `json:"icon"`
}

// GetDownloadPath 获取附件
func GetDownloadPath(c *gin.Context, model_name string, res_id int64, is_login bool) (file []FileItem) {
	db = getDB()
	var attach []model.IrAttachment
	file = make([]FileItem, 0)
	q := db.Where("res_model=? and res_id=? and res_field is null", model_name, res_id).Select("url", "type", "mimetype", "name", "id", "file_size", "Checksum")
	if !is_login {
		q.Where("public=?", true)
	}
	q.Find(&attach)
	for _, v := range attach {
		nu, unit := utils.BeautifyFileSize(v.FileSize)
		var url = v.Url
		if v.Type == "binary" {
			url = "http://" + c.Request.Host + GetAttach(model_name, res_id, v.Checksum)
		}
		preview_url := url + "&preview=1"
		m_arr := strings.Split(v.Mimetype, "/")
		icon_url := fmt.Sprintf("/assets/img/mimetypes/%s", m_arr[0]+".svg")
		if _, path_err := os.Stat(icon_url); os.IsNotExist(path_err) {
			icon_url = fmt.Sprintf("/assets/img/mimetypes/%s", "unknown.svg")
		}
		file = append(file, FileItem{
			Id:         v.Id,
			Url:        url,
			PreviewUrl: preview_url,
			Mimetype:   v.Mimetype,
			Name:       v.Name,
			Num:        fmt.Sprintf("%.2f", nu),
			Unit:       unit,
			Checksum:   v.Checksum,
			Icon:       icon_url,
		})
	}
	return
}
func (a *AttachService) GetIcon() string {
	var icon = "unknown"
	var ext = filepath.Ext(a.Name)
	if utils.StringInArray(ppt_type, a.Mimetype) || strings.Contains(ext, "ppt") {
		icon = "presentation"
	} else if utils.StringInArray(excel_type, a.Mimetype) || strings.Contains(ext, "xls") {
		icon = "spreadsheet"
	} else if utils.StringInArray(word_type, a.Mimetype) || strings.Contains(ext, "doc") {
		icon = "word"
	}
	return fmt.Sprintf("/assets/img/mimetypes/%s.svg", icon)
}
